import selectors
import socket

selector = selectors.DefaultSelector()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("127.0.0.1", 8000))
sock.listen()

# 操作系统级别API 可以观察套接字的传入数据和其它内置事件 从轮询变为消息通知 由于是硬件级别实现的所以监视期间使用CPU资源很低
selector.register(sock, selectors.EVENT_READ)

sock.setblocking(False)
while True:
    events = selector.select(timeout=1)  # select是阻塞调用 返回socket列表
    if len(events) == 0:
        print("No Events waiting")
    for evt, _ in events:
        event_socket = evt.fileobj
        if event_socket == sock:
            conn, addr = sock.accept()
            conn.setblocking(False)
            print(f"I get a connection from {addr}")
            selector.register(conn, selectors.EVENT_READ)
        else:
            data = event_socket.recv(1024)
            print(f"I get data {data}")
            event_socket.send(data)
